using System;

namespace RTMP.SimpleClient.Callbacks
{
    /// <summary>
    /// 回调键，用于标识特定的消息处理器
    /// </summary>
    public readonly struct CallbackKey : IEquatable<CallbackKey>
    {
        /// <summary>
        /// 事务ID
        /// </summary>
        public double TransactionId { get; }

        /// <summary>
        /// 流ID
        /// </summary>
        public uint StreamId { get; }

        /// <summary>
        /// 命令名称（可选，用于进一步区分回调类型）
        /// </summary>
        public string? CommandName { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="actionId">动作ID</param>
        /// <param name="streamId">流ID</param>
        /// <param name="commandName">命令名称（可选）</param>
        public CallbackKey(double actionId, uint streamId, string? commandName = null)
        {
            TransactionId = actionId;
            StreamId = streamId;
            CommandName = commandName;
        }

        /// <summary>
        /// 创建基于动作ID的回调键
        /// </summary>
        public static CallbackKey FromTransactionId(double actionId)
        {
            return new CallbackKey(actionId, 0);
        }

        /// <summary>
        /// 创建基于流ID的回调键
        /// </summary>
        public static CallbackKey FromStreamId(uint streamId)
        {
            return new CallbackKey(0, streamId);
        }

        /// <summary>
        /// 创建基于命令名称的回调键
        /// </summary>
        public static CallbackKey FromCommand(string commandName, uint streamId = 0)
        {
            return new CallbackKey(0, streamId, commandName);
        }

        public bool Equals(CallbackKey other)
        {
            return TransactionId.Equals(other.TransactionId) &&
                   StreamId == other.StreamId &&
                   string.Equals(CommandName, other.CommandName, StringComparison.Ordinal);
        }

        public override bool Equals(object? obj)
        {
            return obj is CallbackKey other && Equals(other);
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(TransactionId, StreamId, CommandName);
        }

        public static bool operator ==(CallbackKey left, CallbackKey right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(CallbackKey left, CallbackKey right)
        {
            return !left.Equals(right);
        }

        public override string ToString()
        {
            return $"ActionId={TransactionId}, StreamId={StreamId}, Command={CommandName ?? "null"}";
        }
    }
}